vimfandomcom-20200223-history
Create underlines, overlines, and strikethroughs using combining characters
This tip provides an easy method to enter Unicode combining characters into text. Unicode contains "combining" code points that modify the appearance of the previous character. Several of these can be used to create text with lines running through them, including U+0305 (COMBINING OVERLINE), U+0332 (COMBINING LOW LINE), U+0333 (COMBINING DOUBLE LOW LINE), and U+0336 (COMBINING LONG STROKE OVERLAY). This is done by putting the appropriate combining character after each printable character in the text. To create these effects easily, you can add the following commands to your vimrc. Set up Unicode Unicode needs to be enabled so Vim will render combining characters properly. See Working with Unicode. Specifically, the 'fileencoding' and 'encoding' options should be set to a Unicode encoding such as utf-8. Define commands " modify selected text using combining diacritics command! -range -nargs=0 Overline call s:CombineSelection(, , '0305') command! -range -nargs=0 Underline call s:CombineSelection(, , '0332') command! -range -nargs=0 DoubleUnderline call s:CombineSelection(, , '0333') command! -range -nargs=0 Strikethrough call s:CombineSelection(, , '0336') function! s:CombineSelection(line1, line2, cp) execute 'let char = "\u'.a:cp.'"' execute a:line1.','.a:line2.'s/\%V[^:cntrl:]/&'.char.'/ge' endfunction Each command (:Overline, :Underline, :DoubleUnderline, and :Strikethrough) allows you to add a particular effect to the text. To use them, visually select the portion of the text you want to change. You can use regular visual, line-wise, or block-wise visual modes. With the text still selected, enter the command name (for example, enter :Underline). You will see that the previously selected text has been underlined. If you use a command frequently, you may want to define a mapping to make it easier. For example, the following will overline selected text when OO is typed: vnoremap OO :Overline Explanation *The commands add a combining character after each non-control character within the selected area in the given range. *If you invoke the commands while the selection is still active, the range will appear on the command line. *The combining characters are encoded in strings using Unicode escapes (for example, "\u0305"). *The characters are inserted only after non-control (printable) characters. If they come after control characters, the text is not well-formed and will not render correctly. *The pattern searches for a character prefixed by \%V: that means the character is only matched if it is within the previous selection. To delete a combining character, first use :set delcombine. * Comments The original script did not operate on the last selected character on my system. For example, selecting "xyz" and entering :Overline would overline xy only. I have patched the script with the following change: " Changed original line: execute a:line1.','.a:line2.'s/\%V[^:cntrl:]\%V/&'.char.'/ge' " to what is now in script: execute a:line1.','.a:line2.'s/\%V[^:cntrl:]/&'.char.'/ge' I have mentioned this change in case it breaks anything. JohnBeckett 08:12, June 13, 2011 (UTC) :The reason is, \%V is a little bit buggy and not zero-width. This is mentioned in todo.txt. Chrisbra 11:27, June 14, 2011 (UTC) Thrilling; now what if I strikethrough a whole block of text, like several paragraphs, but then want to unstrikethrough only a portion thereof, like two sentence? Am I stuck with using 'x' on each and every character?